// components
import SxViewer from '@Components/Viewer'
import SxFilterFieldSetting from '@Components/Search/FilterFieldSetting'
import SxTableButtonGroup from './components/SxTableButtonGroup'
import SxTableExport from './components/SxTableExport'
import SxTableImport from './components/SxTableImport'
import SxTableReportExport from './components/SxTableReportExport'
import SxVContextmenu from './components/vContextmenu'
import VXETable from 'vxe-table'
// utils
import createBem from '@Components/assets/js/utils/bem'
import { convertCamelcase, getSlot } from './utils'
import { clearEvent } from '@Components/Table/utils'

// register custom render
import './render'

// mixin
// 保存 Table 的 ref
import saveTableRefMixin from './tableMixin/saveTableRefMixin'
// 混入原生表格的 methods
import originMethodsMixin from './tableMixin/originMethodsMixin'
// 表格列的处理
import columnsMixin from './tableMixin/columnsMixin'
// 图片 hover 预览的处理
import imageViewerMixin from './tableMixin/imageViewerMixin'
// 列宽，列隐藏，列排序的处理
import customizeColumnsMixin from './tableMixin/customizeColumnsMixin'
// 表格数据获取的处理
import fetchDataMixin from './tableMixin/fetchDataMixin'
// 表格事件处理
import selectionMixin from './tableMixin/selectionMixin'
// 客制化事件处理
import customizedEmitMixin from './tableMixin/customizedEmitMixin'
// 导出处理
import exportMixin from './tableMixin/exportMixin'
// // 导入处理
import importMixin from './tableMixin/importMixin'
// 常规处理
import routineMixin from './tableMixin/routineMixin'

// config
import { tableNamespace } from './config'
import { globalConfig } from '@Components/Table/config'

// style
import './index.scss'

VXETable.interceptor.add('event.clearFilter', clearEvent)
VXETable.interceptor.add('event.clearActived', clearEvent)
VXETable.setup(globalConfig)

const bem = createBem(tableNamespace)
export default {
  mixins: [
    saveTableRefMixin,
    originMethodsMixin,
    columnsMixin,
    customizeColumnsMixin,
    fetchDataMixin,
    imageViewerMixin,
    selectionMixin,
    customizedEmitMixin,
    exportMixin,
    importMixin,
    routineMixin
  ],
  inheritAttrs: false,
  props: {
    buttonList: {
      type: Array,
      default() {
        return []
      }
    },
    id: {
      type: String,
      required: true
    },
    selectOptionsList: {
      type: Object,
      required: false,
      default: null
    }
  },
  data() {
    return {
      clientHeight: 65,
      // Associate `SxViewer` components
      isHover: false,
      vContextmenuItems: []
    }
  },
  mounted() {
    if (this.buttonList.length !== 0) {
      const { clientHeight } = document.getElementById(`${this.id}_button`)
      if (clientHeight) {
        this.clientHeight = clientHeight + 20
      }
    }
  },
  methods: {
    vContextmenuBuild(obj, row) {
      this.vContextmenuItems = obj.list.map(i => ({ ...i, row }))
    },
    slotsBuild(tableColumns) {
      const slotsOption = {}
      tableColumns.forEach(item => {
        if (item.slotsOption) {
          const field = item.slots?.default ?? item.field
          let contentSlot = null
          if (item.slots?.default) {
            contentSlot = getSlot(this, field)
          }
          switch (item.slotsOption.type) {
            case 'vContextmenu':
              slotsOption[field] = props => {
                return (<SxVContextmenu
                  on={{ 'contextmenu': this.vContextmenuBuild.bind(null, item.slotsOption, props) }}
                  refContextmenu={this.$refs?.vContextmenu ?? {}}
                >{contentSlot.bind(null, props) ?? props.row[field]}
                </SxVContextmenu>)
              }
              break
          }
        }
      })
      return slotsOption
    }
  },
  render() {
    /** @type {{props: import('vxe-table').Table}} */
    const mergeProps = {
      props: {
        highlightHoverRow: true,
        highlightCurrentRow: true,
        // showOverflow: true,
        showHeaderOverflow: true,
        autoResize: true,
        customConfig: {
          storage: { resizable: true }
        },
        ...convertCamelcase(this.$attrs),
        id: this.id,
        checkboxConfig: this.checkboxConfig,
        resizableConfig: this.resizableConfig,
        proxyConfig: this.proxyConfig,
        pagerConfig: this.tablePage,
        sortConfig: this.sortConfig,
        editConfig: this.editConfig,
        loading: this.loading
      },
      scopedSlots: this.$scopedSlots,
      on: {
        ...this.$listeners,
        'current-change': this.currentChange,
        'cell-click': this.cellClick,
        'edit-closed': this.editClosed
      }
    }

    if (this.buttonList.length > 0) {
      mergeProps.props.height = mergeProps.props.height - this.clientHeight
    }

    mergeProps.scopedSlots = {
      ...mergeProps.scopedSlots, ...this.slotsBuild(this.tableColumns)
    }
    return (
      <div class={bem()}>
        <v-contextmenu ref='vContextmenu'>
          {
            this.vContextmenuItems.map(item => {
              return (<v-contextmenu-item on={{ click: item.callback.bind(this, item.row) }} >{item.label}</v-contextmenu-item>)
            })
          }
          <v-contextmenu-item on={{ click: () => this.$refs.vContextmenu.hide.call() }} >取消操作</v-contextmenu-item>
        </v-contextmenu>

        {this.buttonList.length !== 0 ? <SxTableButtonGroup button-list={this.buttonList} id={`${this.id}_button`}></SxTableButtonGroup> : ''}
        <vxe-grid
          class={bem('table')}
          ref='tableNode'
          size={this.$store.getters.size}
          border
          resizable
          columns={this.tableColumns}
          {...mergeProps}
        />

        {/* Associate `imageViewerMixin` mixin */}
        <div ref='tooltipEl' class={bem('tooltip')} v-show={this.isHover}>
          <div data-popper-arrow class={bem('tooltip__arrow')} />
        </div>
        <SxViewer ref='sxViewerNode' />

        {/* Associate `customizeColumnsMixin` mixin */}
        <SxFilterFieldSetting
          title='表格列配置'
          data={this.columnSettingDialog.columns}
          visible={this.columnSettingDialog.visible}
          on={{
            'update:visible': $event =>
              (this.columnSettingDialog.visible = $event),
            'update-filtered': this.handleColumnSettingClick
          }}
        />

        {/* Associate `exportMixin` */}
        {
          this.sxExportConfig && this.sxTableExportVisible && (
            <SxTableExport
              ref='tableExport'
              visible={this.sxTableExportVisible}
              export-config={this.sxExportConfig}
              query-field={{
                ...this._tableParams,
                ...this.pageInfo
              }}
              selections-key={this.exportSelectKey}
              selections={this.selections}
              on={{
                'update:visible': $event => (this.sxTableExportVisible = $event)
              }}
            />
          )
        }
        {
          this.uploadConfig && (
            <SxTableImport
              ref='tableExport'
              upload-config={this.uploadConfig}
              on={{
                handleFileSuccess: this.handleFileSuccess
              }}
            />
          )
        }
        {
          this.reportExportKey && (
            <SxTableReportExport
              ref='tableReportExport'
              data-key={this.reportExportKey}
              query-field={{ ...this._tableParams, ...this.pageInfo }}
            />
          )
        }
      </div >
    )
  }
}
